<template>
	<view v-if="loaded" class="uploader-bd">
		<view class="uploader-files">
			<block v-for="(item, index) in uploadBeforeList" :key="index">
				<view class="uploader-file" :class="[item.upload_percent < 100 ? 'uploader-file-status' : '']" @click="handlePreviewImage(index)">
					<image class="uploader-img" :style="uploadImgSize" :src="item.path" mode="aspectFill" />
					<view class="img-removeicon right" @click.stop="handleRemoveImage(index)" v-show="deleteButton">×</view>
					<view class="loader-filecontent" v-if="item.upload_percent < 100">{{ item.upload_percent }}%</view>
				</view>
			</block>
			<view v-show="uploadLen < limit" hover-class="uploader-hover" class="uploader-inputbox" @click="handleChooseImage" :style="uploadImgSize">
				<image style="uploader-inputbox-image" :src="require('@/static/images/common/photo.png')" mode="widthFix"></image>
			</view>
		</view>
	</view>
</template>

<script>
import { getToken } from "@/utils/auth";
import config from '@/config'
import { isHttp } from "@/utils/validate"
import { deleteFile } from "@/api/common/upload.js"
export default {
	data() {
		return {
			// 上传的图片数量
			uploadLen: 0,
			// 图片文件路径列表
			uploadCache: [],
			// 获取的图片列表
			uploadCacheList: [],
			// 本地选择的图片列表
			uploadBeforeList: [],
		};
	},
	name: 'UploadImage',
	model: {
		prop: 'value',
		event: 'input'
	},
	props: {
		value: {
			type: String, 
			default: ''
		},
		// 上传样式宽高
		uploadImgSize: {
			type: String,
			default: 'width:162rpx;height:162rpx;'
		},
		// 上传数量
		limit: {
			type: [Number, String],
			default: 9
		},
		// 是否显示删除
		deleteButton: {
			type: Boolean,
			default: true
		},
		// 服务器预览图片
		imagePreview: {
			type: Array,
			default: () => {
				return [];
			}
		},
	},
	watch: {
		value: function(n, o) {
			let imgs = n?n.split(","):[];
			this.uploadBeforeList = imgs.map(path=>{
				return {
					fileName: path,
					path: isHttp(path)?path:config.baseUrl + path,
					upload_percent: 100
				}
			});
			this.uploadLen = this.uploadBeforeList.length;
			this.uploadBeforeList.map(item => {
				this.uploadCacheList.push(item);
			});
			console.log('-----',this.uploadLen , this.limit)
		}
	},
	async created() {
		let self = this;
		setTimeout(() => {
			this.uploadBeforeList = this.uploadBeforeList.concat(this.imagePreview);
			this.uploadLen = this.uploadBeforeList.length;
			this.imagePreview.map(item => {
				this.uploadCacheList.push(item);
			});
			this.emit();
		}, 300);
	},
	computed: {
		loaded: function() {
			return this.$i18n.locale?true:false;
		}
	},
	methods: {
		/** 上传图片 */
		uploadImage(paths) {
			let self = this;
			// 遍历所有图片路径进行上传
			const promises = paths.map(function(path) {
				const params = {
					url: config.baseUrl + "/common/upload",
					path: path,
					name: 'file',
					header: {
						Authorization: "Bearer " + getToken(),
					},
					self: self
				}
				return promisify(upload)(params);
			});

			uni.showLoading({
				title: this.$i18n.t('upload.img-loading')
			});
			// 当所有图片都上传完成后执行以下代码
			Promise.all(promises)
				.then(function(data) {
					uni.hideLoading();
					self.uploadCacheList.push(...data);
					self.emit();
				})
				.catch(function(res) {
					uni.hideLoading();
				});
		},
		/** 选择图片 */
		handleChooseImage() {
			let self = this;
			uni.chooseImage({
				count: self.limit - self.uploadBeforeList.length,
				sizeType: ['compressed', 'original'],
				sourceType: ['album', 'camera'],
				success: function(res) {
					for (let i = 0, len = res.tempFiles.length; i < len; i++) {
						res.tempFiles[i]['upload_percent'] = 0;
						self.uploadBeforeList.push(res.tempFiles[i]);
					}
					self.uploadCache = res.tempFilePaths;
					self.upload();
				},
				fail: function(err) {
					uni.showToast({
						title: err
					})
				}
			});
		},
		async upload() {
			let self = this;
			await self.uploadImage(self.uploadCache)
		},
		/** 预览图片 */
		handlePreviewImage(idx) {
			let self = this;
			let preview = [];
			for (let i = 0, len = self.uploadBeforeList.length; i < len; i++) {
				preview.push(self.uploadBeforeList[i].path);
			}
			uni.previewImage({
				current: idx,
				urls: preview
			});
		},
		/**
		 * 删除图片
		 * @param {Object} idx 图片列表索引
		 */
		handleRemoveImage(idx) {
			let self = this;
			uni.showModal({
				title: this.$i18n.t('prompted'),
				content: this.$i18n.t('upload.file-delete-prompt'),
				showCancel: true,
				cancelText: this.$i18n.t('cancel'),
				confirmText: this.$i18n.t('delete'),
				success: (res) => {
					if(res.confirm) {
						// 获取要删除的图片
						const removeImage = self.uploadCacheList[idx];
						console.log(removeImage,'image')
						uni.showLoading({
							title: this.$i18n.t('upload.img-deleting')
						})
						deleteFile({
							fileName: removeImage.fileName
						}).then(res=>{
							uni.hideLoading();
							self.uploadBeforeList.splice(idx, 1);
							self.uploadCacheList.splice(idx, 1);
							self.uploadLen = self.uploadBeforeList.length;
							uni.showToast({
								title: this.$i18n.t('upload.img-delete-success')
							});
							self.emit();
						}).catch(err=>{
							uni.hideLoading();
						});
					}
				}
			});
		},
		/** 图片变更事件 */
		emit() {
			this.$emit('input', this.uploadCacheList.map(img=>img.fileName).join(','));
		}
	}
};

const promisify = api => {
	return function(options, ...params) {
		return new Promise(function(resolve, reject) {
			api(
				Object.assign({}, options, {
					success: resolve,
					fail: reject
				}),
				...params
			);
		});
	};
};

/** 上传数据 */
const upload = function(options) {
	let url = options.url,
		self = options.self,
		path = options.path,
		name = options.name,
		header = options.header,
		success = options.success,
		progress = options.progress,
		fail = options.fail;

	const uploadTask = uni.uploadFile({
		url: url,
		filePath: path,
		name: name,
		header: header,
		success: function(res) {
			var data = res.data;
			try {
				data = JSON.parse(res.data);
			} catch (e) {
				throw (e, data);
			}
			// 服务器返回200即代表成功请求
			if (res.statusCode == 200) {
				if (success) {
					success(data);
				}
			} else {
				if (fail) {
					fail(data);
				}
			}
		},
		fail: function(res) {
			if (fail) {
				fail(res);
			}
		}
	});
	// 下载过程中显示进度
	uploadTask.onProgressUpdate(async function(res) {
		for (let i = 0, len = self.uploadBeforeList.length; i < len; i++) {
			self.uploadBeforeList[i]['upload_percent'] = await res.progress;
		}
		self.uploadBeforeList = self.uploadBeforeList;
		self.uploadLen = self.uploadBeforeList.length;
	});
};
</script>

<style lang="scss" scoped>
.uploader-img {
	display: block;
	border-radius: 10rpx;
}

.uploader-input {
	position: absolute;
	z-index: 1;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
}

.uploader-inputbox {
	position: relative;
	margin-bottom: 16rpx;
	box-sizing: border-box;
	background-color: #ededed;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	border-radius: 10rpx;
}

.img-removeicon {
	position: absolute;
	color: #fff;
	height: 40rpx;
	line-height: 40upx;
	z-index: 2;
	text-align: center;
	background-color: #e54d42;
	border-radius: 10rpx 10rpx 0 0 !important;

	&.right {
		width: 100%;
		top: 0;
		right: 0;
	}
}

.uploader-file {
	position: relative;
	margin-right: 16rpx;
	margin-bottom: 16rpx;
	border-radius: 10rpx;
	overflow: hidden;
}

.uploader-file-status:before {
	content: ' ';
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background-color: rgba(0, 0, 0, 0.5);
}

.loader-filecontent {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	color: #fff;
	z-index: 9;
}

.uploader-bd {
	margin: 0;
}

.uploader-files {
	display: flex;
	flex-wrap: wrap;
}

.uploader-file:nth-child(4n + 0) {
	margin-right: 0;
}

.uploader-inputbox > .uploader-inputbox-image {
	text-align: center;
	width: 80%;
	height: 80%
}

.uploader-file-status:after {
	content: ' ';
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background-color: rgba(0, 0, 0, 0.5);
}

.uploader-hover {
	box-shadow: 0 0 0 #e5e5e5;
	background: #e5e5e5;
}
</style>
